package com.mbv5.xml;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.w3c.dom.CharacterData;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * Created by qiao on 2017/1/7.
 */
public class XNode {
    private Node node;
    private Properties properties;
    private XPathParser xPathParser;
    private String name;
    private String body;
    private Properties atrributes;

    public XNode(XPathParser xPathParser, Node node, Properties properties) {
        this.node = node;
        this.properties = properties;
        this.xPathParser = xPathParser;
        this.name = node.getNodeName();
        this.body = parseBody(node);
        this.atrributes = parseAttrbite(node);
    }

    private Properties parseAttrbite(Node n) {
        Properties properties = new Properties();
        NamedNodeMap attributeNodes = n.getAttributes();
        if (null != attributeNodes) {
            for (int i = 0; i < attributeNodes.getLength(); i++) {
                Node attribute = attributeNodes.item(i);
                properties.put(attribute.getNodeName(), attribute.getNodeValue());
            }
        }
        return properties;
    }

    private String parseBody(Node node) {
        String data = getNodeData(node);
        if (null == data) {
            NodeList nodeList = node.getChildNodes();
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node child = nodeList.item(i);
                data = getNodeData(child);
                if (null != data) {
                    break;
                }
            }
        }
        return data;
    }

    private String getNodeData(Node child) {
        if (child.getNodeType() == Node.CDATA_SECTION_NODE ||
                child.getNodeType() == Node.TEXT_NODE) {
            String data = ((CharacterData) child).getData();
            return data;
        }
        return null;
    }

    public XNode evalNode(String expression) {
        return xPathParser.evalNode(node, expression);
    }


    public Properties getChildrenAsProperties() {
        Properties properties = new Properties();
        for (XNode child : getChildren()) {
            String key = child.getStringAttribute("name");
            String value = child.getStringAttribute("value");
            if (key != null && value != null) {
                properties.put(key, value);
            }
        }
        return properties;
    }

    private String getStringAttribute(String name) {
        return getStringAttribute(name, null);
    }

    private String getStringAttribute(String name, String def) {
        String value = atrributes.getProperty(name);
        if (null == value) {
            return def;
        }
        return value;
    }

    public List<XNode> getChildren() {
        List<XNode> childs = new ArrayList<XNode>();
        NodeList nolist = node.getChildNodes();
        if (null != nolist) {
            for (int i = 0, n = nolist.getLength(); i < n; i++) {
                Node node = nolist.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    childs.add(new XNode(xPathParser, node, properties));
                }
            }
        }
        return childs;
    }
}
